#define _USE_MATH_DEFINES
#include <iostream>
#include <cmath>
#include "EquationSolver.h"

using namespace std;

class func1: public Function
{
    public:
        double get_value(double x){
            return sin(x/2.0)-1;
        }
}f1;

class func2: public Function
{
    public:
        double get_value(double x){
            if (cos(x) == 0){
                cout << "Error: 'tan(x)' does not exist!" <<endl;
                return 0;
            }else{
                return exp(x)-tan(x);
            }
        }
}f2;

class func3: public Function
{
    public:
        double get_value(double x){
            return x*x*x-12*x*x+3*x+1;
        }
}f3;

int main()
{
    cout << "Secant Method Test: "<<endl;
    double e = 1e-8;
    double d = 1e-8;
    double m = 30;
    Secant sec_solver(e,d,m);
 
    InitInput input1(f1), input2(f2), input3(f3);
    input1.setSecantInput(0, M_PI_2-e);
    double x1 = sec_solver.solve(input1);
    cout << "the approximate root of f1: x1 = "<< x1 <<endl;
    cout << "the value of the root: f1(x1) = "<< f1.get_value(x1) <<endl;
    cout << endl;

    input2.setSecantInput(1, 1.4);
    double x2 = sec_solver.solve(input2);
    cout << "the approximate root of f2: x2 = "<< x2 <<endl;
    cout << "the value of the root: f2(x2) = "<< f2.get_value(x2) <<endl;
    cout << endl;

    input3.setSecantInput(0, -0.5);
    double x3 = sec_solver.solve(input3);
    cout << "the approximate root of f3: x3 = "<< x3 <<endl;
    cout << "the value of the root: f3(x3) = "<< f3.get_value(x3) <<endl;

    return 0;
}